#pragma once
#include <boost/date_time/posix_time/posix_time.hpp>

typedef boost::posix_time::time_duration TimeDuration;
#define SECONDS(d) ((double)((d).total_milliseconds()) / 1000)

class StopWatch
{
public:
  boost::posix_time::ptime m_Start, m_Stop, m_LastStop;
public:
  StopWatch(void) 
    : m_Start(boost::posix_time::microsec_clock::local_time()), m_Stop(m_Start), m_LastStop(m_Start)
  {
  }

  virtual ~StopWatch(void) 
  {
  }

  void Reset()
  {
    m_Start = boost::posix_time::microsec_clock::local_time();
    m_Stop = m_Start;
    m_LastStop = m_Start;
  }

  boost::posix_time::time_duration GetDuration() // duration from last time this function is called
  {
    m_Stop = boost::posix_time::microsec_clock::local_time();
    boost::posix_time::time_duration duration = m_Stop - m_LastStop;
    m_LastStop = m_Stop;
    return duration;
  }

  boost::posix_time::time_duration GetTotalDuration() // call this
  {
    m_Stop = boost::posix_time::microsec_clock::local_time();
    m_LastStop = m_Stop;
    return m_Stop - m_Start;
  }

};

struct Iteration
{
  int iter;
  double residual;
  TimeDuration duration, compute, communication;
  
  Iteration(int iter_, double residual_, 
	    TimeDuration duration_ = TimeDuration(), 
	    TimeDuration compute_ = TimeDuration(), 
	    TimeDuration communication_ = TimeDuration()) 
    : iter(iter_), residual(residual_), 
    duration(duration_), compute(compute_), communication(communication_)
  {
  }
};

